Существуют ли локальные переменные группы потоков в Java? - PullRequest
9 голосов
/ 07 января 2010

Я ищу класс, похожий на ThreadLocal, который работал бы с группами потоков вместо потоков.

Если бы не было такого класса (в какой-нибудь библиотеке с открытым исходным кодом), как бы вы его реализовали? Какая-то лучшая идея, чем иметь группы потоков в WeakHashMap?

Я реализую инфраструктуру отладки, настраиваемую во время выполнения, с различными параметрами в глобальном, для каждого потока и для группы потоковом контексте. В качестве очень простого примера вы можете получить отчет:

debug.log( category, message);

и укажите, что запись журнала с этой конкретной категорией будет отображаться только при вызове потоком в группе потоков, обслуживающих сетевые запросы.

Ответы [ 3 ]

5 голосов
/ 07 января 2010

ThreadGroup используется редко, поэтому поддержка платформы отсутствует.

Использование [Weak / Identity / Concurrent] HashMap<ThreadGroup,T> сработает, если не очень быстро. Вы действительно хотите, чтобы карта была слабой, идентичной и параллельной, но с библиотекой Java вы можете выбрать только одну, в настоящее время.

Для повышения производительности обратите внимание, что Thread s не изменяется ThreadGroup. Поэтому кешируйте значение с помощью ThreadLocal (переопределить initialValue). ThreadLocal имеет хорошую производительность (пара десятков циклов на get).

5 голосов
/ 07 января 2010

Я бы сохранил держатель значения в локальном потоке и инициализировал бы его одним и тем же держателем значения для всех потоков одной группы.

 public class ThreadGroupLocal<T> extends ThreadLocal<ValueHolder> {
     private static class ValueHolder {
         public Object value;
     }
     // Weak & Concurrent would be even the better, but Java API wont offer that :(
     private static ConcurrentMap<ThreadGroup, ValueHolder> map = new ConcurrentHashMap<ThreadGroup, ValueHolder>;
     private static ValueHolder valueHolderForThread(Thread t) {
         map.putIfAbsent(t.getThreadGroup(), new ValueHolder());
         return map.get(t.getThreadGroup());
     }
     @Override 
     protected ValueHolder initialValue() {
         return valueHolderForThread(Thread.currentThread());
     }
     public T getValue() { (T) get().value; }
     public void setValue(T value) { get().value = value; }
 }

и затем используйте

 ThreadGroupLocal<String> groupLocal = new ThreadGroupLocal<String>();
 groupLocal.setValue("foo");
 //...
 String foo = groupLocal.getValue();

Это (ожидаемо для инициализации) работает точно так же, как локальный поток.

2 голосов
/ 07 января 2010

В последний раз, когда я смотрел на реализацию (ну, несколько лет назад), локальные потоки были реализованы в виде простой хеш-таблицы, проиндексированной по идентификатору потока. Ничего особенного и далеко от эффективности C ++.

Вы можете сделать то же самое и использовать объект группы потоков в качестве ключа для своей собственной хеш-таблицы локальных групп потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...